package jaoso.framework.web.filter;


import jaoso.framework.security.Acl;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.faquir.license.License;
import org.faquir.license.LicenseFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.yl.cap.analyst.config.ContextBean;

import java.io.File;
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * DOCUMENT ME!
 * 
 * @author $author$
 * @version $Revision: 1.2 $
 */
public class AclFilter implements Filter
{
    /** Acl DAO, responsible for reading acl configuration from file */
    private Acl acl;

    /**
     * The filter configuration object we are associated with. If this value is
     * null, this filter instance is not currently configured.
     */
    private FilterConfig config;

    /** DOCUMENT ME! */
    private Log log = LogFactory.getLog(AclFilter.class);

    /**
     * Take this filter out of service.
     */
    public final void destroy()
    {
        config = null;
        acl = null;
    }

    /**
     * Use acl-config.xml to store web pages that can only be viewed by logined
     * user. For every web resource, if it is a protected resource, check if the
     * user has been logined, if not, save corrent page to session, forward to
     * logon page
     * 
     * @param request
     *            The servlet request we are processing
     * @param response
     *            The servlet response we are creating
     * @param chain
     *            The filter chain we are processing
     * 
     * @exception IOException
     *                if an input/output error occurs
     * @exception ServletException
     *                if a servlet error occurs
     */
    public final void doFilter(final ServletRequest request,
            final ServletResponse response, final FilterChain chain)
            throws IOException, ServletException
    {
        HttpServletRequest hreq = (HttpServletRequest) request;
        String[] urls = StringUtils.split(hreq.getRequestURI(), "/");
        String url = urls[(urls.length - 1)];
        log.info("filter url: " + url);
        HttpServletResponse hr = (HttpServletResponse)response;
        //check license
        License license = LicenseFactory.getLicense();
        ServletContext application = config.getServletContext();
        boolean res = false;
        try
        {
            res = license.canUse(new File(application
                    .getRealPath("/conf/license/" + "license")));
        }
        catch (Exception e)
        {
            res = false;
        }
        if (!res)
        {
            hr.sendRedirect("/Reporter/view/util/licenseFailure.vm");
            return;
        }

        //check login
        if (!isLogin(hreq) && acl.isProtectedResource(url))
        {
            hr = (HttpServletResponse)response;
            hr.sendRedirect("/Reporter/view/manage/inLogin.vm");

            return;
        }

        if (acl.isProtectedResource(url))
        {
            //get subject
            final String group = (String) hreq.getSession().getAttribute(
                    "group");

            if (!acl.hasRight(url, group))
            {
                /*config.getServletContext().getRequestDispatcher(
                        "/noRight.do?method=noRight")
                        .forward(request, response);*/
                hr = (HttpServletResponse)response;
                hr.sendRedirect("/Reporter/view/util/noRight.vm");
                return;
            }
        }

        // Pass control on to the next filter
        chain.doFilter(request, response);
    }

    /**
     * @param hreq
     * @return
     */
    private boolean isLogin(HttpServletRequest hreq)
    {
        //check login
        boolean isLogin = false;
        HttpSession session = hreq.getSession();

        isLogin = (session != null) && !session.isNew()
                && (session.getAttribute("account") != null)
                && (session.getAttribute("group") != null);

        return isLogin;
    }
    
    private int checkAccess(ServletResponse response,HttpServletRequest hreq,String url)
    {
        //cheak license
        License license = LicenseFactory.getLicense();
        int res = 0;
        try
        {
            res = license.canUse(ContextBean.licenseFile) ? 0 : 1;
            //check login
            if (!isLogin(hreq) && acl.isProtectedResource(url))
            {
                res = 2;
            }
        }
        catch (Exception e)
        {
            res = 1;
            e.printStackTrace();
        }
        return res;
    }

    /**
     * Place this filter into service. Read acl configuration from file
     * 
     * @param filterConfig
     *            The filter configuration object
     * @exception ServletException
     *                error
     */
    public final void init(final FilterConfig filterConfig)
            throws ServletException
    {
        config = filterConfig;

        ServletContext context = filterConfig.getServletContext();
        ApplicationContext ctx = WebApplicationContextUtils
        .getWebApplicationContext(context);

        acl = (Acl) ctx.getBean("acl");
    }
}